字符串文字量

  字符串文字量是用双引号括起的字符序列:

"this is a string"

一个字符串文字量里包含的字符个数比它看起来的字符数多一个,它总由一个空字符'\0'结束。空字符的值是0。例如,

sizeof("Bohr") == 5

字符串文字量的类型是“适当个数的const字符的数组”,所以“Bohr”的类型就是const char[5]。

  可以用字符串文字量给一个char*赋值。允许这样做是因为在C和C++原来的定义里,字符串文字量的类型就是char*。允许将字符串文字量赋值给char*保证了成百万行的C和C++程序继续为合法程序。但试图通过这样的指针去修改字符串文字量将是一个错误:

    void f()
    {
        char* p = "Plato";
        p[4] = 'e';            // 错误❌:给常量赋值;结果无定义
    }

一般来说,这类错误未必能在运行之前捕捉到,而各种实现在对本规则的强调方面也会很不相同。参见B.2.3节。将字符串文字量当做常量,不仅因为这样做很明显,而且它也能允许实现对于字符串文字量的存储和访问做一些效果很显著的优化。

  如果我们希望一个字符串保证能够被修改,那么就必须将有关的字符复制到数组里:

    void f()
    {
        char p[] = "Zeno";        // p是5个char的数组
        p[0] = 'R';               // 可以
    }

字符串文字量是静态分配的,所以让函数返回它们是安全的。例如,

    const char* error_message(int i)
    {
        // ...
        return "range error";
    }

保存“range error”的存储区在error_message()的调用之后并不会丢掉。

  两个同样的字符串文字量是否被分配在一起,这一点由实现确定(C.1节)。例如,

    const char* p = "Heraclitus";
    const char* q = "Heraclitus";
    void g()
    {
        if(p==q) cout << "one!\n";        // 结果是由实现确定的
        // ...
    }

请注意,在应用于指针时,==比较的是地址(指针的值),而不是被指的东西。

  空字符串写成一对连续的引号"",它的类型是const char[1]。

  为表示非打印字符而提供的反斜线约定(C.3.2节)也可以用在字符串里。这就使我们可以在字符串里表示诸如双引号(")和转义字符反斜线(\)等。这类字符中最常见的就是换行符'\n'。例如,

cout << "beep at end of message\a\n";

转义字符'\a'是ASCII字符BEL(也被称做警铃),它会导致发出某种声音。

  在字符串里不能有“真正的”换行:

    "this is not a string
    but a syntax error"

为使程序比较整洁,可以将长字符串通过空白字符断开。例如,

    char alpha[] = "abcdefghijklmnopqrstuvwxyz"
                   "ABCDEFGHIJKLMNOPQRSTUVWXYZ";

编译器将拼接起连续的字符串,所以对alpha可以等价地用下面这个字符串来做初始化:

"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";

将空字符放到字符串里也是可能的,但是大部分程序将不会去考虑在这个字符的后面还有其他字符。举例来说,字符串"Jers\000Munk"将被各种标准库函数,例如strcpy()和strlen(),当做“Jens”看待;参见20.4.1节。

  带有前缀L的字符串,例如L"angst",是宽字符的字符串(4.3节、C.3.3节),其类型是const wchar_t[]。

🔚